package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"os"
	"sync"
	"time"
)

// 日志系统
type Logger struct {
	infoLogger  *log.Logger
	errorLogger *log.Logger
	debugMode   bool
}

func NewLogger(debugMode bool) *Logger {
	return &Logger{
		infoLogger:  log.New(os.Stdout, "INFO: ", log.Ldate|log.Ltime),
		errorLogger: log.New(os.Stderr, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile),
		debugMode:   debugMode,
	}
}

func (l *Logger) Info(message string) {
	l.infoLogger.Println(message)
}

func (l *Logger) Error(message string, err error) {
	l.errorLogger.Printf("%s: %v\n", message, err)
}

func (l *Logger) Debug(message string) {
	if l.debugMode {
		log.Printf("DEBUG: %s\n", message)
	}
}

// CHIP-8 模拟器核心结构
type Chip8 struct {
	mu         sync.RWMutex
	logger     *Logger
	display    [32][64]uint8 // 显示缓冲区 (32x64)
	memory     [4096]uint8   // 内存 (4KB)
	vx         [16]uint8     // 通用寄存器 V0-VF
	key        [16]uint8     // 按键状态
	stack      [16]uint16    // 堆栈
	oc         uint16        // 当前操作码
	pc         uint16        // 程序计数器
	sp         uint16        // 堆栈指针
	iv         uint16        // 索引寄存器
	delayTimer uint8         // 延迟计时器
	soundTimer uint8         // 声音计时器
	shouldDraw bool          // 需要重绘标志
	romLoaded  bool          // ROM已加载标志
	cycleCount uint64        // 执行周期计数
}

// 初始化CHIP-8模拟器
func InitChip8(logger *Logger) *Chip8 {
	instance := &Chip8{
		logger: logger,
	}

	// 加载字体到内存 (0x000-0x1FF)
	fontSet := []uint8{
		0xF0, 0x90, 0x90, 0x90, 0xF0, //0
		0x20, 0x60, 0x20, 0x20, 0x70, //1
		0xF0, 0x10, 0xF0, 0x80, 0xF0, //2
		0xF0, 0x10, 0xF0, 0x10, 0xF0, //3
		0x90, 0x90, 0xF0, 0x10, 0x10, //4
		0xF0, 0x80, 0xF0, 0x10, 0xF0, //5
		0xF0, 0x80, 0xF0, 0x90, 0xF0, //6
		0xF0, 0x10, 0x20, 0x40, 0x40, //7
		0xF0, 0x90, 0xF0, 0x90, 0xF0, //8
		0xF0, 0x90, 0xF0, 0x10, 0xF0, //9
		0xF0, 0x90, 0xF0, 0x90, 0x90, //A
		0xE0, 0x90, 0xE0, 0x90, 0xE0, //B
		0xF0, 0x80, 0x80, 0x80, 0xF0, //C
		0xE0, 0x90, 0x90, 0x90, 0xE0, //D
		0xF0, 0x80, 0xF0, 0x80, 0xF0, //E
		0xF0, 0x80, 0xF0, 0x80, 0x80, //F
	}

	copy(instance.memory[:len(fontSet)], fontSet)

	// 设置程序计数器初始值 (CHIP-8程序从0x200开始)
	instance.pc = 0x200
	instance.logger.Info("CHIP-8 emulator initialized")

	return instance
}

// 加载CHIP-8程序到内存
func (c *Chip8) LoadProgram(data []byte) error {
	c.mu.Lock()
	defer c.mu.Unlock()

	if len(data) > 4096-512 { // CHIP-8程序加载到0x200位置(512字节)
		err := errors.New("program too large for memory")
		c.logger.Error("Failed to load program", err)
		return err
	}

	// 清空内存(保留字体区域)
	for i := 512; i < 4096; i++ {
		c.memory[i] = 0
	}

	// 加载程序
	copy(c.memory[512:], data)

	// 重置状态
	c.pc = 0x200
	c.sp = 0
	c.iv = 0
	c.delayTimer = 0
	c.soundTimer = 0
	c.shouldDraw = true
	c.romLoaded = true
	c.cycleCount = 0

	c.logger.Info(fmt.Sprintf("Program loaded successfully, size: %d bytes", len(data)))
	return nil
}

// 执行一个CPU周期
func (c *Chip8) Cycle() bool {
	c.mu.Lock()
	defer c.mu.Unlock()

	if !c.romLoaded {
		c.logger.Debug("ROM not loaded, skipping cycle")
		return false
	}

	c.cycleCount++
	if c.cycleCount%1000 == 0 {
		c.logger.Debug(fmt.Sprintf("Executed %d cycles", c.cycleCount))
	}

	// 读取操作码 (两个字节)
	c.oc = (uint16(c.memory[c.pc]) << 8) | uint16(c.memory[c.pc+1])

	// 记录操作码执行
	if c.logger.debugMode {
		c.logger.Debug(fmt.Sprintf("Cycle %d: Executing opcode 0x%04X at 0x%04X", c.cycleCount, c.oc, c.pc))
	}

	// 解码并执行操作码
	switch c.oc & 0xF000 {
	case 0x0000:
		switch c.oc & 0x000F {
		case 0x0000: // 0x00E0 - 清屏
			c.logger.Debug("Executing opcode 0x00E0: Clear screen")
			for i := 0; i < 32; i++ {
				for j := 0; j < 64; j++ {
					c.display[i][j] = 0
				}
			}
			c.shouldDraw = true
			c.pc += 2
		case 0x000E: // 0x00EE - 从子程序返回
			c.logger.Debug("Executing opcode 0x00EE: Return from subroutine")
			if c.sp == 0 {
				err := errors.New("stack underflow when returning from subroutine")
				c.logger.Error("Error executing opcode", err)
				return false
			}
			c.sp--
			c.pc = c.stack[c.sp] + 2
		default:
			c.logger.Error(fmt.Sprintf("Unknown opcode: 0x%04X", c.oc), nil)
			c.pc += 2
		}
	case 0x1000: // 0x1NNN - 跳转到地址NNN
		c.logger.Debug(fmt.Sprintf("Executing opcode 0x1NNN: Jump to 0x%04X", c.oc&0x0FFF))
		c.pc = c.oc & 0x0FFF
	case 0x2000: // 0x2NNN - 调用子程序NNN
		c.logger.Debug(fmt.Sprintf("Executing opcode 0x2NNN: Call subroutine at 0x%04X", c.oc&0x0FFF))
		if c.sp >= 16 {
			err := errors.New("stack overflow when calling subroutine")
			c.logger.Error("Error executing opcode", err)
			return false
		}
		c.stack[c.sp] = c.pc
		c.sp++
		c.pc = c.oc & 0x0FFF
	case 0x3000: // 0x3XNN - 如果VX等于NN，则跳过下一条指令
		x := (c.oc & 0x0F00) >> 8
		c.logger.Debug(fmt.Sprintf("Executing opcode 0x3XNN: Skip if V%X == 0x%02X", x, c.oc&0x00FF))
		if c.vx[x] == uint8(c.oc&0x00FF) {
			c.pc += 4
		} else {
			c.pc += 2
		}
	case 0x4000: // 0x4XNN - 如果VX不等于NN，则跳过下一条指令
		x := (c.oc & 0x0F00) >> 8
		c.logger.Debug(fmt.Sprintf("Executing opcode 0x4XNN: Skip if V%X != 0x%02X", x, c.oc&0x00FF))
		if c.vx[x] != uint8(c.oc&0x00FF) {
			c.pc += 4
		} else {
			c.pc += 2
		}
	case 0x5000: // 0x5XY0 - 如果VX等于VY，则跳过下一条指令
		x := (c.oc & 0x0F00) >> 8
		y := (c.oc & 0x00F0) >> 4
		c.logger.Debug(fmt.Sprintf("Executing opcode 0x5XY0: Skip if V%X == V%X", x, y))
		if c.vx[x] == c.vx[y] {
			c.pc += 4
		} else {
			c.pc += 2
		}
	case 0x6000: // 0x6XNN - 设置VX为NN
		x := (c.oc & 0x0F00) >> 8
		c.logger.Debug(fmt.Sprintf("Executing opcode 0x6XNN: Set V%X to 0x%02X", x, c.oc&0x00FF))
		c.vx[x] = uint8(c.oc & 0x00FF)
		c.pc += 2
	case 0x7000: // 0x7XNN - 将NN加到VX
		x := (c.oc & 0x0F00) >> 8
		c.logger.Debug(fmt.Sprintf("Executing opcode 0x7XNN: Add 0x%02X to V%X", c.oc&0x00FF, x))
		c.vx[x] += uint8(c.oc & 0x00FF)
		c.pc += 2
	case 0x8000:
		x := (c.oc & 0x0F00) >> 8
		y := (c.oc & 0x00F0) >> 4

		switch c.oc & 0x000F {
		case 0x0000: // 0x8XY0 - 设置VX为VY的值
			c.logger.Debug(fmt.Sprintf("Executing opcode 0x8XY0: Set V%X to V%X", x, y))
			c.vx[x] = c.vx[y]
			c.pc += 2
		case 0x0001: // 0x8XY1 - VX = VX OR VY
			c.logger.Debug(fmt.Sprintf("Executing opcode 0x8XY1: V%X = V%X OR V%X", x, x, y))
			c.vx[x] |= c.vx[y]
			c.pc += 2
		case 0x0002: // 0x8XY2 - VX = VX AND VY
			c.logger.Debug(fmt.Sprintf("Executing opcode 0x8XY2: V%X = V%X AND V%X", x, x, y))
			c.vx[x] &= c.vx[y]
			c.pc += 2
		case 0x0003: // 0x8XY3 - VX = VX XOR VY
			c.logger.Debug(fmt.Sprintf("Executing opcode 0x8XY3: V%X = V%X XOR V%X", x, x, y))
			c.vx[x] ^= c.vx[y]
			c.pc += 2
		case 0x0004: // 0x8XY4 - VX += VY，VF设置为进位标志
			c.logger.Debug(fmt.Sprintf("Executing opcode 0x8XY4: V%X += V%X, set VF to carry", x, y))
			if c.vx[y] > 0xFF-c.vx[x] {
				c.vx[0xF] = 1 // 进位
			} else {
				c.vx[0xF] = 0
			}
			c.vx[x] += c.vx[y]
			c.pc += 2
		case 0x0005: // 0x8XY5 - VX -= VY，VF设置为借位标志
			c.logger.Debug(fmt.Sprintf("Executing opcode 0x8XY5: V%X -= V%X, set VF to borrow", x, y))
			if c.vx[y] > c.vx[x] {
				c.vx[0xF] = 0 // 借位
			} else {
				c.vx[0xF] = 1
			}
			c.vx[x] -= c.vx[y]
			c.pc += 2
		case 0x0006: // 0x8XY6 - VX右移一位，VF设置为最低位
			c.logger.Debug(fmt.Sprintf("Executing opcode 0x8XY6: Shift V%X right, set VF to LSB", x))
			c.vx[0xF] = c.vx[x] & 0x1
			c.vx[x] >>= 1
			c.pc += 2
		case 0x0007: // 0x8XY7 - VX = VY - VX，VF设置为借位标志
			c.logger.Debug(fmt.Sprintf("Executing opcode 0x8XY7: V%X = V%X - V%X, set VF to borrow", x, y, x))
			if c.vx[x] > c.vx[y] {
				c.vx[0xF] = 0 // 借位
			} else {
				c.vx[0xF] = 1
			}
			c.vx[x] = c.vx[y] - c.vx[x]
			c.pc += 2
		case 0x000E: // 0x8XYE - VX左移一位，VF设置为最高位
			c.logger.Debug(fmt.Sprintf("Executing opcode 0x8XYE: Shift V%X left, set VF to MSB", x))
			c.vx[0xF] = (c.vx[x] >> 7) & 0x1
			c.vx[x] <<= 1
			c.pc += 2
		default:
			c.logger.Error(fmt.Sprintf("Unknown opcode: 0x%04X", c.oc), nil)
			c.pc += 2
		}
	case 0x9000: // 0x9XY0 - 如果VX不等于VY，则跳过下一条指令
		x := (c.oc & 0x0F00) >> 8
		y := (c.oc & 0x00F0) >> 4
		c.logger.Debug(fmt.Sprintf("Executing opcode 0x9XY0: Skip if V%X != V%X", x, y))
		if c.vx[x] != c.vx[y] {
			c.pc += 4
		} else {
			c.pc += 2
		}
	case 0xA000: // 0xANNN - 设置I为地址NNN
		c.logger.Debug(fmt.Sprintf("Executing opcode 0xANNN: Set I to 0x%04X", c.oc&0x0FFF))
		c.iv = c.oc & 0x0FFF
		c.pc += 2
	case 0xB000: // 0xBNNN - 跳转到地址NNN + V0
		c.logger.Debug(fmt.Sprintf("Executing opcode 0xBNNN: Jump to 0x%04X + V0", c.oc&0x0FFF))
		c.pc = (c.oc & 0x0FFF) + uint16(c.vx[0])
	case 0xC000: // 0xCXNN - VX = 随机数 AND NN
		x := (c.oc & 0x0F00) >> 8
		c.logger.Debug(fmt.Sprintf("Executing opcode 0xCXNN: V%X = random AND 0x%02X", x, c.oc&0x00FF))
		c.vx[x] = uint8(rand.Intn(256)) & uint8(c.oc&0x00FF)
		c.pc += 2
	case 0xD000: // 0xDXYN - 在(VX, VY)绘制N行高的精灵，VF设置为碰撞标志
		x := c.vx[(c.oc&0x0F00)>>8] % 64
		y := c.vx[(c.oc&0x00F0)>>4] % 32
		height := c.oc & 0x000F

		c.logger.Debug(fmt.Sprintf("Executing opcode 0xDXYN: Draw sprite at (%d, %d), height %d", x, y, height))

		c.vx[0xF] = 0 // 无碰撞

		for yLine := uint16(0); yLine < height; yLine++ {
			if int(y)+int(yLine) >= 32 {
				continue // 超出屏幕范围
			}

			pixel := c.memory[c.iv+yLine]
			for xLine := uint16(0); xLine < 8; xLine++ {
				if int(x)+int(xLine) >= 64 {
					continue // 超出屏幕范围
				}

				if (pixel & (0x80 >> xLine)) != 0 {
					// 当前像素位置
					screenX := int(x) + int(xLine)
					screenY := int(y) + int(yLine)

					// 检查碰撞 (异或操作前检查是否为1)
					if c.display[screenY][screenX] == 1 {
						c.vx[0xF] = 1
					}

					// 绘制像素 (异或操作)
					c.display[screenY][screenX] ^= 1
				}
			}
		}

		c.shouldDraw = true
		c.pc += 2
	case 0xE000:
		x := (c.oc & 0x0F00) >> 8

		switch c.oc & 0x00FF {
		case 0x009E: // 0xEX9E - 如果键码等于VX的值，则跳过下一条指令
			c.logger.Debug(fmt.Sprintf("Executing opcode 0xEX9E: Skip if key %X is pressed", x))
			if c.key[c.vx[x]] != 0 {
				c.pc += 4
			} else {
				c.pc += 2
			}
		case 0x00A1: // 0xEXA1 - 如果键码不等于VX的值，则跳过下一条指令
			c.logger.Debug(fmt.Sprintf("Executing opcode 0xEXA1: Skip if key %X is not pressed", x))
			if c.key[c.vx[x]] == 0 {
				c.pc += 4
			} else {
				c.pc += 2
			}
		default:
			c.logger.Error(fmt.Sprintf("Unknown opcode: 0x%04X", c.oc), nil)
			c.pc += 2
		}
	case 0xF000:
		x := (c.oc & 0x0F00) >> 8

		switch c.oc & 0x00FF {
		case 0x0007: // 0xFX07 - VX = 延迟计时器的值
			c.logger.Debug(fmt.Sprintf("Executing opcode 0xFX07: Set V%X to delay timer value", x))
			c.vx[x] = c.delayTimer
			c.pc += 2
		case 0x000A: // 0xFX0A - 等待按键，将按键值存入VX
			c.logger.Debug(fmt.Sprintf("Executing opcode 0xFX0A: Wait for key press and store in V%X", x))
			keyPressed := false
			for i := 0; i < 16; i++ {
				if c.key[i] != 0 {
					c.vx[x] = uint8(i)
					keyPressed = true
					break
				}
			}

			if !keyPressed {
				return false // 不增加PC，等待按键
			}

			c.pc += 2
		case 0x0015: // 0xFX15 - 延迟计时器 = VX
			c.logger.Debug(fmt.Sprintf("Executing opcode 0xFX15: Set delay timer to V%X", x))
			c.delayTimer = c.vx[x]
			c.pc += 2
		case 0x0018: // 0xFX18 - 声音计时器 = VX
			c.logger.Debug(fmt.Sprintf("Executing opcode 0xFX18: Set sound timer to V%X", x))
			c.soundTimer = c.vx[x]
			c.pc += 2
		case 0x001E: // 0xFX1E - I += VX
			c.logger.Debug(fmt.Sprintf("Executing opcode 0xFX1E: Add V%X to I", x))
			if c.iv+uint16(c.vx[x]) > 0xFFF {
				c.vx[0xF] = 1 // 溢出
			} else {
				c.vx[0xF] = 0
			}
			c.iv += uint16(c.vx[x])
			c.pc += 2
		case 0x0029: // 0xFX29 - I = 字符VX的字体地址
			c.logger.Debug(fmt.Sprintf("Executing opcode 0xFX29: Set I to font address of character V%X", x))
			c.iv = uint16(c.vx[x]) * 5 // 每个字符占用5字节
			c.pc += 2
		case 0x0033: // 0xFX33 - 将VX的BCD码存入I, I+1, I+2
			c.logger.Debug(fmt.Sprintf("Executing opcode 0xFX33: Store BCD of V%X at I, I+1, I+2", x))
			c.memory[c.iv] = c.vx[x] / 100         // 百位
			c.memory[c.iv+1] = (c.vx[x] / 10) % 10 // 十位
			c.memory[c.iv+2] = c.vx[x] % 10        // 个位
			c.pc += 2
		case 0x0055: // 0xFX55 - 将V0到VX存入I开始的内存
			c.logger.Debug(fmt.Sprintf("Executing opcode 0xFX55: Store V0-V%X starting at I", x))
			for i := 0; i <= int(x); i++ {
				c.memory[c.iv+uint16(i)] = c.vx[i]
			}
			c.pc += 2
		case 0x0065: // 0xFX65 - 从I开始的内存读取数据到V0到VX
			c.logger.Debug(fmt.Sprintf("Executing opcode 0xFX65: Load V0-V%X from memory starting at I", x))
			for i := 0; i <= int(x); i++ {
				c.vx[i] = c.memory[c.iv+uint16(i)]
			}
			c.pc += 2
		default:
			c.logger.Error(fmt.Sprintf("Unknown opcode: 0x%04X", c.oc), nil)
			c.pc += 2
		}
	default:
		c.logger.Error(fmt.Sprintf("Unknown opcode: 0x%04X", c.oc), nil)
		c.pc += 2
	}

	// 更新计时器
	if c.delayTimer > 0 {
		c.delayTimer--
	}

	if c.soundTimer > 0 {
		if c.soundTimer == 1 {
			c.logger.Info("Sound timer expired, beep!")
		}
		c.soundTimer--
	}

	return true
}

// 获取显示缓冲区
func (c *Chip8) GetDisplay() [32][64]uint8 {
	c.mu.RLock()
	defer c.mu.RUnlock()

	return c.display
}

// 设置按键状态
func (c *Chip8) SetKey(key uint8, pressed bool) {
	c.mu.Lock()
	defer c.mu.Unlock()

	if key < 16 {
		if pressed {
			c.logger.Info(fmt.Sprintf("Key %X pressed", key))
			c.key[key] = 1
		} else {
			c.logger.Info(fmt.Sprintf("Key %X released", key))
			c.key[key] = 0
		}
	} else {
		c.logger.Error(fmt.Sprintf("Invalid key code: %d", key), nil)
	}
}

// 检查是否需要绘制
func (c *Chip8) NeedsDraw() bool {
	c.mu.RLock()
	defer c.mu.RUnlock()

	return c.shouldDraw
}

// 重置绘制标志
func (c *Chip8) ResetDrawFlag() {
	c.mu.Lock()
	defer c.mu.Unlock()

	c.shouldDraw = false
}

// 检查ROM是否已加载
func (c *Chip8) IsRomLoaded() bool {
	c.mu.RLock()
	defer c.mu.RUnlock()

	return c.romLoaded
}

// 获取声音计时器值
func (c *Chip8) GetSoundTimer() uint8 {
	c.mu.RLock()
	defer c.mu.RUnlock()

	return c.soundTimer
}

// 显示缓冲区JSON表示
type DisplayResponse struct {
	Display      [32][64]uint8 `json:"display"`
	NeedsDraw    bool          `json:"needsDraw"`
	SoundPlaying bool          `json:"soundPlaying"`
	Registers    struct {
		V [16]uint8 `json:"v"`
		I uint16    `json:"i"`
	} `json:"registers"`
	PC     uint16   `json:"pc"`
	SP     uint16   `json:"sp"`
	Stack  []uint16 `json:"stack"`
	Timers struct {
		Delay uint8 `json:"delay"`
		Sound uint8 `json:"sound"`
	} `json:"timers"`
}

// 按键请求JSON表示
type KeyRequest struct {
	Key     uint8 `json:"key"`
	Pressed bool  `json:"pressed"`
}

// API控制器
type APIController struct {
	emulator *Chip8
	logger   *Logger
}

func NewAPIController(emulator *Chip8, logger *Logger) *APIController {
	return &APIController{
		emulator: emulator,
		logger:   logger,
	}
}

// 获取模拟器状态
func (a *APIController) GetStatus(w http.ResponseWriter, r *http.Request) {
	a.logger.Info("Handling GET /status request")

	w.Header().Set("Content-Type", "application/json")

	// 获取显示数据
	display := a.emulator.GetDisplay()
	needsDraw := a.emulator.NeedsDraw()

	// 检查声音计时器
	soundPlaying := a.emulator.GetSoundTimer() > 0

	// 构建响应
	response := DisplayResponse{
		Display:      display,
		NeedsDraw:    needsDraw,
		SoundPlaying: soundPlaying,
	}

	// 编码为JSON
	jsonData, err := json.Marshal(response)
	if err != nil {
		a.logger.Error("Failed to encode status data", err)
		http.Error(w, "Failed to encode status data", http.StatusInternalServerError)
		return
	}

	w.Write(jsonData)
}

// 获取显示数据
func (a *APIController) GetDisplay(w http.ResponseWriter, r *http.Request) {
	a.logger.Info("Handling GET /display request")

	w.Header().Set("Content-Type", "application/json")

	// 获取显示数据
	display := a.emulator.GetDisplay()
	needsDraw := a.emulator.NeedsDraw()

	// 调试：检查显示缓冲区是否有内容
	hasContent := false
	for y := 0; y < 32; y++ {
		for x := 0; x < 64; x++ {
			if display[y][x] != 0 {
				hasContent = true
				break
			}
		}
		if hasContent {
			break
		}
	}
	a.logger.Info(fmt.Sprintf("Display has content: %v", hasContent))

	// 检查声音计时器
	soundPlaying := a.emulator.GetSoundTimer() > 0

	// 构建响应
	response := struct {
		Display      [32][64]uint8 `json:"display"`
		NeedsDraw    bool          `json:"needsDraw"`
		SoundPlaying bool          `json:"soundPlaying"`
	}{
		Display:      display,
		NeedsDraw:    needsDraw,
		SoundPlaying: soundPlaying,
	}

	// 编码为JSON
	jsonData, err := json.Marshal(response)
	if err != nil {
		a.logger.Error("Failed to encode display data", err)
		http.Error(w, "Failed to encode display data", http.StatusInternalServerError)
		return
	}

	w.Write(jsonData)
}

// 处理按键请求
func (a *APIController) HandleKey(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		a.logger.Error("Method not allowed for /key", nil)
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	a.logger.Info("Handling POST /key request")

	// 解析JSON请求
	var request KeyRequest
	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		a.logger.Error("Invalid request body for /key", err)
		http.Error(w, "Invalid request body", http.StatusBadRequest)
		return
	}

	// 设置按键状态
	a.emulator.SetKey(request.Key, request.Pressed)

	w.WriteHeader(http.StatusOK)
}

// 处理重置请求
func (a *APIController) HandleReset(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		a.logger.Error("Method not allowed for /reset", nil)
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	a.logger.Info("Handling POST /reset request")

	// 重新加载ROM
	romFile := os.Args[1]
	data, err := os.ReadFile(romFile)
	if err != nil {
		a.logger.Error("Failed to reload ROM", err)
		http.Error(w, fmt.Sprintf("Failed to reload ROM: %v", err), http.StatusInternalServerError)
		return
	}

	if err := a.emulator.LoadProgram(data); err != nil {
		a.logger.Error("Error reloading program", err)
		http.Error(w, fmt.Sprintf("Error reloading program: %v", err), http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
}

// CORS中间件 - 添加必要的CORS头部
func corsMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// 设置允许的域名（这里设为*表示允许所有域名，生产环境建议指定具体域名）
		w.Header().Set("Access-Control-Allow-Origin", "*")
		// 设置允许的HTTP方法
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
		// 设置允许的HTTP头部
		w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
		// 设置是否允许携带凭证（如cookies）
		w.Header().Set("Access-Control-Allow-Credentials", "true")

		// 处理预检请求（OPTIONS）
		if r.Method == "OPTIONS" {
			w.WriteHeader(http.StatusOK)
			return
		}

		// 继续处理请求
		next.ServeHTTP(w, r)
	})
}

func main() {
	if len(os.Args) < 2 {
		fmt.Println("Usage: chip8 <rom_file> [port] [--debug]")
		return
	}

	romFile := os.Args[1]
	port := "8080"
	debugMode := false

	// 解析命令行参数
	for i := 2; i < len(os.Args); i++ {
		if os.Args[i] == "--debug" {
			debugMode = true
		} else {
			port = os.Args[i]
		}
	}

	// 初始化日志系统
	logger := NewLogger(debugMode)
	logger.Info("Starting CHIP-8 emulator server")
	logger.Info(fmt.Sprintf("Debug mode: %v", debugMode))

	// 初始化模拟器
	emulator := InitChip8(logger)

	// 加载ROM
	data, err := os.ReadFile(romFile)
	if err != nil {
		logger.Error("Failed to load ROM", err)
		fmt.Printf("Failed to load ROM: %v\n", err)
		return
	}

	if err := emulator.LoadProgram(data); err != nil {
		logger.Error("Error loading program", err)
		fmt.Printf("Error loading program: %v\n", err)
		return
	}

	// 启动模拟器循环协程
	go func() {
		logger.Info("Starting emulator loop")
		// CHIP-8通常以60Hz的频率运行
		ticker := time.NewTicker(time.Second / 60)
		defer ticker.Stop()

		for range ticker.C {
			emulator.Cycle()
		}
	}()

	// 初始化API控制器
	controller := NewAPIController(emulator, logger)

	// 设置HTTP路由
	mux := http.NewServeMux()
	// GET
	mux.HandleFunc("/status", controller.GetStatus)
	mux.HandleFunc("/display", controller.GetDisplay)
	// POST
	mux.HandleFunc("/key", controller.HandleKey)
	mux.HandleFunc("/reset", controller.HandleReset)

	// 应用CORS中间件
	server := &http.Server{
		Addr:    ":" + port,
		Handler: corsMiddleware(mux),
	}

	// 启动HTTP服务器
	logger.Info(fmt.Sprintf("Server listening on port %s", port))
	logger.Info("Ready to accept requests")
	log.Fatal(server.ListenAndServe())
}
